'''
 * CaRComp Execution Environment
 * 
 * Copyright (C) 2011 Taylor L. Riche
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
'''

from carcomp.framework import abstraction, connector
from carcomp.apps.gamma import bloom, hjoin, constants, mergesplit

class ParBloomHashJoinAbs(abstraction.Abstraction):
    
    def __init__(self, name):
        '''
        Constructor
        '''
        abstraction.Abstraction.__init__(self, name)
        for i in range(constants.SPLIT_NUM):
            hj = hjoin.HashJoin('HashJoin_abs%s'%i)
            self.add_component(hj)
            blm = bloom.Bloom('Bloom_abs%s'%(constants.SPLIT_NUM+i))
            self.add_component(blm)
            bf = bloom.BFilter('BFilter_abs%s'%(2*constants.SPLIT_NUM+i))
            self.add_component(bf)
        splitA = mergesplit.Split('SplitA_abs6', constants.SPLIT_NUM, constants.JOIN_KEYA)
        self.add_component(splitA)
        splitB = mergesplit.Split('SplitB_abs7', constants.SPLIT_NUM, constants.JOIN_KEYB)
        self.add_component(splitB)
        mrg = mergesplit.Merge('Merge_abs8', constants.SPLIT_NUM)
        self.add_component(mrg)
        self.add_port('A', (splitA, 'in'))
        self.add_port('B', (splitB, 'in'))
        self.add_port('AB', (mrg, 'out'), output=True)
        for i in range(constants.SPLIT_NUM):
            conn = connector.Connector(splitA.get_endpoint('out%s'%i), self.get_component('Bloom_abs%s'%(constants.SPLIT_NUM+i)).get_endpoint('A'))
            self.add_connector(conn)
            conn = connector.Connector(splitB.get_endpoint('out%s'%i), self.get_component('BFilter_abs%s'%(2*constants.SPLIT_NUM+i)).get_endpoint('B'))
            self.add_connector(conn)
            conn = connector.Connector(self.get_component('Bloom_abs%s'%(constants.SPLIT_NUM+i)).get_endpoint('sendMap'),
                                       self.get_component('BFilter_abs%s'%(2*constants.SPLIT_NUM+i)).get_endpoint('BM'))
            self.add_connector(conn)
            conn = connector.Connector(self.get_component('Bloom_abs%s'%(constants.SPLIT_NUM+i)).get_endpoint('sendA'),
                                       self.get_component('HashJoin_abs%s'%i).get_endpoint('A'))
            self.add_connector(conn)
            conn = connector.Connector(self.get_component('BFilter_abs%s'%(2*constants.SPLIT_NUM+i)).get_endpoint('BPrime'),
                                       self.get_component('HashJoin_abs%s'%i).get_endpoint('B'))
            self.add_connector(conn)
            conn = connector.Connector(self.get_component('HashJoin_abs%s'%i).get_endpoint('AB'),
                                       mrg.get_endpoint('in%s'%i))
            self.add_connector(conn)

class BloomHashJoinAbs(abstraction.Abstraction):
    '''
    classdocs
    '''

    def __init__(self, name):
        '''
        Constructor
        '''
        abstraction.Abstraction.__init__(self, name)
        hj = hjoin.HashJoin('HashJoin_abs0')
        blm = bloom.Bloom('Bloom_abs1')
        bf = bloom.BFilter('BFilter_abs2')
        self.add_component(hj)
        self.add_component(blm)
        self.add_component(bf)
        self.add_port('A', (blm, 'A'))
        self.add_port('B', (bf, 'B'))
        self.add_port('AB', (hj, 'AB'), output=True)
        blm_hj = connector.Connector(blm.get_endpoint('sendA'), hj.get_endpoint('A'))
        self.add_connector(blm_hj)
        blm_bf = connector.Connector(blm.get_endpoint('sendMap'), bf.get_endpoint('BM'))
        self.add_connector(blm_bf)
        bf_hj = connector.Connector(bf.get_endpoint('BPrime'), hj.get_endpoint('B'))
        self.add_connector(bf_hj)

        